home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et3_0-a1.lha / et3 / src / CheapText.C < prev    next >
C/C++ Source or Header  |  1992-05-21  |  5KB  |  263 lines

  1. #ifdef __GNUG__
  2. #pragma implementation
  3. #endif
  4.  
  5. #include "CheapText.h"
  6.  
  7. #include "Class.h"
  8. #include "RegularExp.h"
  9. #include "Port.h" 
  10. #include "Error.h"
  11. #include "Math.h"
  12.  
  13. const int cInitCap= 16;  
  14.  
  15. //---- CheapText ------------------------------------------------------------
  16.  
  17. NewMetaImpl(CheapText,Text, (T(next), T(size), TV(cont,next)));
  18.  
  19. CheapText::CheapText(int s, Font *fd)
  20.     size= Math::Max(cInitCap, s);
  21.     cont= new byte[size];
  22.     next= 0; 
  23.     Init(next, fd);
  24. }
  25.  
  26. CheapText::CheapText(byte *t, int len, Font *fd)
  27. {   
  28.     int ll= len;
  29.  
  30.     if (ll == -1)
  31.     next= strlen((char*)t); 
  32.     else
  33.     next= len;
  34.  
  35.     size= Math::Max(cInitCap,(next / 5 + 1)* 6); // give some initial free space
  36.     cont= new byte[size];
  37.     MemCpy(cont, t, next);
  38.     Init(next, fd);
  39. }
  40.  
  41. void CheapText::Init(int, Font *fd)
  42. {
  43.     SetFont(fd);
  44.     SetDefTab(fd->Width((byte*)"        ",8));
  45.     Terminate();
  46. }
  47.  
  48. void CheapText::InitNew()
  49. {
  50.     Text::InitNew();
  51.     Init(0, gSysFont);
  52. }
  53.  
  54. CheapText::~CheapText()
  55. {
  56.     SafeDelete(cont);
  57. }
  58.  
  59. void CheapText::Terminate()
  60. {
  61.     if (IsTerminated())
  62.     return;
  63.     byte null= '\0';
  64.     InsertBytes(&null, 1, Size(), Size());    
  65. }
  66.  
  67. void CheapText::ReplaceRange(int from, int to, Text *src, int sfrom, int sto)
  68. {
  69.     CheapText *ct;
  70.     byte *buf= 0;
  71.     
  72.     if (!CheckRange(End(), from, to))
  73.     Error("PasteText", "out of range");
  74.     
  75.     if (!src->IsKindOf(CheapText)) { // convert
  76.     int s= sto-sfrom;
  77.     buf= new byte[s+1];
  78.     src->CopyInStr(buf, s+1, sfrom, sto);
  79.     sto= sto-sfrom;
  80.     sfrom= 0;
  81.     ct= new CheapText(buf, s);
  82.     } else
  83.     ct= (CheapText*)src; 
  84.  
  85.     InsertBytes(ct->cont+sfrom, sto-sfrom, from, to);
  86.  
  87.     if (buf) {
  88.     delete buf;
  89.     delete ct;
  90.     }
  91. }
  92.  
  93. Text *CheapText::MakeScratchText(byte *buf, int len) 
  94. {
  95.     if (buf)
  96.     return new CheapText(buf, len);
  97.     return new CheapText(len);
  98. }
  99.  
  100. void CheapText::CopyInStr(byte *str, int size, int from, int to)
  101. {
  102.     if (!CheckRange(next, from, to) || str == 0)
  103.     return;
  104.  
  105.     register int l= Math::Min(to, from+size-1) - from;
  106.     MemCpy(str, &cont[from], l);
  107.     str[l]= '\0';
  108. }
  109.  
  110. void CheapText::AddChar(int at, byte b)
  111. {
  112.     InsertBytes(&b, 1, at, at);
  113. }
  114.  
  115. byte *CheapText::GetLineAccess(byte**, int from, int to)
  116. {
  117.     if (!CheckRange(next, from, to))
  118.     return 0;
  119.     return &cont[from];
  120. }
  121.  
  122. int CheapText::Search(RegularExp *rex, int *nMatched, int start, int range, 
  123.                          bool dir)
  124. {
  125.     if (dir == cSearchForward) 
  126.     return rex->SearchForward((char*)cont, nMatched, start, End(), range, 0);
  127.     return rex->SearchBackward((char*)cont, nMatched, start, End(), range, 0); 
  128. }
  129.  
  130. void CheapText::InsertBytes(byte *c, int n, int from, int to)
  131. {
  132.     int shift= n - (to - from);
  133.  
  134.     if (HighWaterMark(shift))
  135.     Expand(GrowSize(size+shift));
  136.  
  137.     if (shift < 0)
  138.     MemCpy(&cont[to+shift], &cont[to], next-to);
  139.     else if (shift > 0)
  140.     MemCpy(&cont[from+shift], &cont[from], next-from);
  141.  
  142.     //---- insert pasted text
  143.     MemCpy(&cont[from], c, n);
  144.     next += shift;
  145.     if (LowWaterMark())
  146.     Expand(size/2);
  147. }
  148.  
  149. byte& CheapText::operator[](int i)
  150. {
  151.     if (!CheckRange(next, i, i))
  152.     i= size-1; 
  153.     return cont[i];
  154. }
  155.  
  156. int CheapText::Size()
  157. {
  158.     return next;
  159. }   
  160.  
  161. void CheapText::Expand(int newSize)                                         
  162. {
  163.     if (newSize < Size())  // texts never shrinks
  164.     return;
  165.     cont= (byte*) Realloc(cont, newSize);
  166.     next= Math::Min(newSize, next);
  167.     size= newSize;
  168. }
  169.  
  170. TextIter *CheapText::MakeIterator(int from, int to)
  171. {
  172.     return new CheapTextIter(this,from,to);
  173. }
  174.  
  175. OStream& CheapText::PrintOn(OStream &s)
  176. {
  177.     Text::PrintOn(s); 
  178.     return s.PrintString(cont, next);
  179. }
  180.  
  181. IStream& CheapText::ReadFrom(IStream& s)
  182. {
  183.     SafeDelete(cont);
  184.     Text::ReadFrom(s);
  185.     s.ReadString(&cont, &size);
  186.     next= size;
  187.     return s;
  188. }
  189.  
  190. OStream& CheapText::PrintOnAsPureText(OStream &s)
  191. {
  192.     s.write(cont, End());
  193.     return s;
  194. }
  195.  
  196. IStream& CheapText::ReadFromAsPureText(IStream& s, long sizeHint)
  197. {
  198.     char ch;
  199.  
  200.     if (sizeHint > 0) {
  201.     int delta= (int)(sizeHint - size); // !!!
  202.     if (delta > 0)
  203.         Expand(delta + 50);
  204.     }
  205.     next= 0; 
  206.     while (s.get(ch)) {
  207.     if (HighWaterMark(1))
  208.         Expand(GrowSize(size+1));
  209.     cont[next++]= ch;
  210.     }
  211.     if (!s.eof())
  212.     Error("ReadFromAsPureText", "something strange happened");
  213.     Terminate();
  214.     return s;
  215. }
  216.  
  217. //----- class CheapTextIter ---------------------------------------------
  218.  
  219. CheapTextIter::CheapTextIter(Text *s, int from, int to) : TextIter(s, from, to)
  220. {
  221.     if (!s->IsKindOf(CheapText))
  222.     Error("CheapTextIter::CheapTextIter", "CheapText expected");
  223.     font= s->GetFont();
  224. }
  225.  
  226. int CheapTextIter::operator()(int *w, LineDesc* ld)  
  227. {
  228.     CheapText *ctp= (CheapText*)ct;
  229.     if (ld) 
  230.     ld->FromFont(font);
  231.     unget= ce;
  232.     if (ce == upto)
  233.     return cEOT;
  234.     int ch= ctp->cont[ce++];
  235.     if (w)
  236.     *w= font->Width(ch);
  237.     return ch;
  238. }
  239.  
  240. int CheapTextIter::Token(int *w,LineDesc* ld)  
  241. {
  242.     CheapText *ctp= (CheapText*)ct;
  243.     unget= ce;
  244.     *w= 0;
  245.     if (ld) 
  246.     ld->FromFont(font);
  247.     if (ce >= upto)
  248.     return cEOT;
  249.  
  250.     register int ch= ctp->CharAt(ce);
  251.     if (Iswordwrap(ch)) {
  252.     *w= font->Width(ch);
  253.     ce++;
  254.     return (ch);
  255.     }
  256.     while (ce < upto && !Iswordwrap(ctp->CharAt(ce))) {
  257.     ch= ctp->CharAt(ce++);
  258.     *w+= font->Width(ch);
  259.     }
  260.     return (ch);
  261. }
  262.